import { defineStore } from 'pinia';
import { useIdle } from '@vueuse/core';
import mitt from 'mitt';
import { uniqueSlash } from '~/utils/urlUtils';

export type MessageEvent = {
    data?: any;
    type?: 'ping' | 'close' | 'updatePermsAndMenus' | 'updateOnlineUserCount';
};

type Events = {
    onlineUser: number;
};

export const useSSEStore = defineStore('sse', () => {
    const emitter = mitt<Events>();
    const userStore = useUserStore();
    const { idle } = useIdle(5 * 60 * 1000); // 5 min
    let eventSource: EventSource | null = null; // SSE实例

    const serverConnected = ref(true);
    const onlineUserCount = ref(0);

    watch(serverConnected, (val) => {
        if (val && userStore.accessToken) {
            initServerMsgListener();
        } else {
            closeEventSource();
        }
    });

    watch(idle, (idleValue) => {
        if (idleValue) {
            closeEventSource();
        } else if (userStore.accessToken) {
            setServerConnectStatus(true);
        }
    });

    /** 监听来自服务端推送的消息 */
    const initServerMsgListener = async () => {
        if (eventSource) {
            eventSource.close();
        }

        const sseUrl = uniqueSlash(`${import.meta.env.VITE_BASE_API_URL}/api/sse/?token=${userStore.accessToken}`);

        eventSource = new EventSource(sseUrl);

        // 处理 SSE 传递的数据
        eventSource.onmessage = (event) => {
            const { type, data } = JSON.parse(event.data) as MessageEvent;
            // 服务器关闭 SSE 连接
            if (type === 'close') {
                closeEventSource();
            }
            // 当用户的权限及菜单有变更时，重新获取权限及菜单
            else if (type === 'updatePermsAndMenus') {
            }
            // 在线用户数量变更时
            else if (type === 'updateOnlineUserCount') {
                onlineUserCount.value = ~~data;
                emitter.emit('onlineUser', onlineUserCount.value);
            }
        };
        eventSource.onerror = (err) => {
            console.log('eventSource err', err);
            closeEventSource();
        };
    };

    /** 关闭SSE连接 */
    const closeEventSource = () => {
        serverConnected.value = false;
        eventSource?.close();
        eventSource = null;
    };

    /** 设置服务端连接状态 */
    const setServerConnectStatus = (isConnect: boolean) => {
        serverConnected.value = isConnect;
    };

    return {
        emitter,
        serverConnected,
        onlineUserCount,
        initServerMsgListener,
        closeEventSource,
        setServerConnectStatus,
    };
});
